package com.cosina.game.robodefence.model;

import android.graphics.Point;

import com.cosina.game.robodefence.core.BattleField;
import com.cosina.game.robodefence.findway.Path;
import com.cosina.game.robodefence.findway.FindWayFacade;
import com.cosina.game.robodefence.util.UpCount;
import com.cosina.game.robodefence.util.World;

public class Way {
	public final Point entry, exit;
	public final BattleField field;
	private Path path;
	
	private final UpCount movePart = new UpCount(20);
	
	public Way(Point entry, Point exit,BattleField field){
		this.entry = entry;
		this.exit = exit;
		this.field = field;
		this.path = FindWayFacade.getPath(field, this);
	}
	
	public Way(Way way){
		this.entry = new Point(way.entry);
		this.exit = new Point(way.exit);
		this.field = way.field;
		this.path = way.path;
		this.movePart.value = 9;
	}
	
	public String getDirection(){
		if(movePart.value>=10){
			return path.exitDirection;
		}else {
			return path.entryDirection;
		}
	}
	
	public void refind(){
		Path beforePath = this.path.before;
		this.path = FindWayFacade.getPath(field, this);
		if(null != beforePath){
			this.path.setBefore(new Path(beforePath.x,beforePath.y,null));
			if(path.entryDirection ==  path.exitDirection){
				if(movePart.value < 10){
					this.movePart.value = 20 - movePart.value;
				}
			}
		}
	}
	
	public Path getPath(){
		return path;
	}
	
	public int getPxX(int speed){
		return path.x * 40 + getXspan(speed);
	}
	
	public int getPxY(int speed){
		return path.y * 40 + getYspan(speed);
	}
	
	
	private int getYspan(int speed){
		int movePartValue = movePart.value;
		if(movePartValue<10){
			if(path.entryDirection == World.BOTTOM){
				return -20 + speed * movePartValue;
			}else if(path.entryDirection == World.TOP){
				return 20 - speed * movePartValue;
			}
		}else{
			if(path.exitDirection == World.TOP){
				return -speed * movePartValue + 20;
			}else if(path.exitDirection == World.BOTTOM){
				return speed * movePartValue - 20;
			}
		}
		return 0;
	}
	
	private int getXspan(int speed){
		int movePartValue = movePart.value;
		if(movePartValue<10){
			if(path.entryDirection == World.RIGHT){
				return -20 + speed * movePartValue;
			}else if(path.entryDirection == World.LEFT){
				return 20 - speed * movePartValue;
			}
		}else{
			if(path.exitDirection == World.LEFT){
				return -speed * movePartValue + 20;
			}else if(path.exitDirection == World.RIGHT){
				return speed * movePartValue - 20;
			}
		}
		return 0;
	}
	
	
	private boolean isCross(int x, int y){
		Path some = path;
		do{
			if(null == some){
				return false;
			}
			if(some.x == x && some.y == y){
				return true;
			}
			some = some.next;
		}while(true);
	}
	
	public boolean canBuild(int x, int y){
		if(isCross(x, y)){
			return field.canBuilder4Way(x, y, this);
		}else{
			return true;
		}
	}
	
	public void updateIfCross(int x, int y){
		if(isCross(x,y)){
			refind();
		}
	}
	
	public void update(){
			refind();
	}
	
	public final boolean isBlock(){
		return null == FindWayFacade.getRoute(field, entry, exit);
	}

	public void move() {
		if(movePart.upToAlram()){
			this.path = path.next;
			this.entry.x = path.x;
			this.entry.y = path.y;
		}
	}
	
	public boolean noPath() {
		return path.next == null && movePart.value == 10;
	}
}
